package org.chen.scene.service.geocode;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.util.UriUtils;
import org.chen.common.scene.dto.BaiduGeocodingResponse;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap;
import java.util.Map;

@Slf4j
@Service
public class BaiduGeocodingApiService {
    
    private static final String BAIDU_GEOCODING_URL = "https://api.map.baidu.com/geocoding/v3";
    
    @Value("${baidu.map.ak:4wKPSUNnCjxoDfNipGlOTOHWQxE96YHQ}")
    private String baiduAk;
    
    private final ObjectMapper objectMapper = new ObjectMapper();
    
    /**
     * 调用百度地理编码API获取城市坐标
     */
    public BaiduGeocodingResponse.Result.Location getCityCoordinatesFromBaidu(String cityName) {
        try {
            log.info("调用百度API查询城市坐标: {}", cityName);
            
            Map<String, String> params = new LinkedHashMap<>();
            params.put("address", cityName);
            params.put("output", "json");
            params.put("ak", baiduAk);
            
            String response = sendHttpRequest(BAIDU_GEOCODING_URL, params);
            log.debug("百度API响应: {}", response);
            
            BaiduGeocodingResponse baiduResponse = objectMapper.readValue(response, BaiduGeocodingResponse.class);
            
            if (baiduResponse.getStatus() == 0 && baiduResponse.getResult() != null 
                && baiduResponse.getResult().getLocation() != null) {
                
                BaiduGeocodingResponse.Result.Location location = baiduResponse.getResult().getLocation();
                log.info("百度API成功返回城市 {} 的坐标: [{}, {}]", 
                    cityName, location.getLat(), location.getLng());
                return location;
            } else {
                log.warn("百度API查询失败，城市: {}, 状态码: {}",
                    cityName, baiduResponse.getStatus());
                return null;
            }
            
        } catch (Exception e) {
            log.error("调用百度地理编码API异常，城市: {}", cityName, e);
            return null;
        }
    }
    
    /**
     * 发送HTTP请求
     */
    private String sendHttpRequest(String baseUrl, Map<String, String> params) throws Exception {
        if (baseUrl == null || baseUrl.isEmpty() || params == null || params.isEmpty()) {
            throw new IllegalArgumentException("URL或参数不能为空");
        }
        
        StringBuilder queryString = new StringBuilder();
        queryString.append(baseUrl).append("?");
        
        for (Map.Entry<String, String> entry : params.entrySet()) {
            queryString.append(entry.getKey()).append("=")
                      .append(UriUtils.encode(entry.getValue(), StandardCharsets.UTF_8))
                      .append("&");
        }
        
        if (queryString.length() > 0) {
            queryString.deleteCharAt(queryString.length() - 1);
        }
        
        URL url = new URL(queryString.toString());
        log.debug("请求URL: {}", queryString.toString());
        
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");
        connection.setConnectTimeout(5000);
        connection.setReadTimeout(10000);
        connection.connect();
        
        int responseCode = connection.getResponseCode();
        if (responseCode != HttpURLConnection.HTTP_OK) {
            throw new RuntimeException("HTTP请求失败，响应码: " + responseCode);
        }
        
        try (InputStreamReader isr = new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8);
             BufferedReader reader = new BufferedReader(isr)) {
            
            StringBuilder buffer = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                buffer.append(line);
            }
            return buffer.toString();
        }
    }
}